using System;
using System.Collections.Generic;
using System.Text;

namespace CodeDomAssistant
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Configuration;
    using System.Xml;
    using System.Windows.Forms;

    public class Config
    {
        private Hashtable settings = null;

        public Config()
        {
            settings = new Hashtable();
            loadSettings();
        }

        public string this[int index]
        {
            get
            {
                object setting = settings[index];

                if (setting == null)
                    return string.Empty;

                return setting.ToString();
            }
        }

        public string this[string itemName]
        {
            get
            {
                object setting = settings[itemName];

                if (setting == null)
                    return string.Empty;

                return setting.ToString();
            }
            set
            {
                if (settings[itemName] == null)
                    settings.Add(itemName, value);
                else
                    settings[itemName] = value;
            }
        }

        public bool GetBoolValue(string itemName)
        {
            object setting = settings[itemName];

            if (setting == null)
                return false;

            string val = setting.ToString();

            if (val.Length == 0)
                return false;

            return bool.Parse(val);
        }

        public string[] GetStringList(string listName)
        {
            List<string> list = new List<string>();

            object setting = settings[listName];
            if (setting == null)
                return list.ToArray();

            string val = setting.ToString();
            if (val.Length == 0)
                return list.ToArray();

            return val.Split(',');
        }

        public void SetStringList(string listName, string[] list)
        {
            string value = string.Empty;
            foreach (string s in list)
            {
                if (value.Length != 0) value += ",";
                value += s;
            }

            settings[listName] = value;
        }

        public void loadSettings()
        {
            settings.Clear();

            foreach (string key in ConfigurationManager.AppSettings.AllKeys)
            {
                settings.Add(key, ConfigurationManager.AppSettings[key]);
            }
        }

        public void saveSettings()
        {
            // Search for application config file

            // find the App.config file
            string path = Application.StartupPath + @"\App.config";
            if (System.IO.File.Exists(path))
            {
                saveSettings(path);
            }
            else
            {
                // No App.config, try to find <appname>.exe.config file
                path = Application.ExecutablePath + ".config";
                if (System.IO.File.Exists(path))
                {
                    saveSettings(path);

                    // maybe we are in Visual Studio, so we check for App.config
                    path = Application.StartupPath + @"\..\..\App.config";
                    if (System.IO.File.Exists(path))
                    {
                        saveSettings(path);
                    }
                }
                else
                {
                    // exe.config not found, then we will create an App.config file
                    path = Application.StartupPath + @"\App.config";

                    saveSettings(path);
                }
            }
        }

        public void saveSettings(string path)
        {
            XmlElement elem = null;
            string key = String.Empty;

            XmlDocument xml = new XmlDocument();

            // Load existing App.config file
            if (System.IO.File.Exists(path))
                xml.Load(path);

            XmlNodeList nodes = xml.SelectNodes("configuration/appSettings/add");

            foreach (string configKey in settings.Keys)
            {
                bool foundKey = false;

                foreach (XmlNode node in nodes)
                {
                    elem = (XmlElement)node;

                    key = elem.GetAttribute("key").ToString();
                    if (string.Compare(key, configKey) == 0)
                    {
                        elem.SetAttribute("value", settings[key].ToString());
                        foundKey = true;
                        break;
                    }
                }

                if (!foundKey)
                {
                    XmlNode appsettingNode = xml.SelectSingleNode("configuration/appSettings");

                    // AppSetting Node?
                    if (appsettingNode == null)
                    {
                        XmlNode configurationNode = xml.SelectSingleNode("configuration");
                        if (configurationNode != null)
                        {
                            appsettingNode = xml.CreateElement("appSettings");

                            configurationNode.AppendChild(appsettingNode);
                        }
                    }

                    if (appsettingNode != null)
                    {
                        XmlElement addNode = (XmlElement)xml.CreateElement("add");
                        addNode.Attributes.Append(xml.CreateAttribute("key"));
                        addNode.Attributes.Append(xml.CreateAttribute("value"));

                        addNode.SetAttribute("key", configKey);
                        addNode.SetAttribute("value", settings[configKey].ToString());

                        appsettingNode.AppendChild(addNode);
                    }
                }
            }

            xml.Save(path);
        }
    }

    // Typed Configuration Class
    public class CodeDomAssistantConfig : Config
    {
        static CodeDomAssistantConfig m_current = null;

        static public CodeDomAssistantConfig Current
        {
            get
            {
                if (m_current == null)
                {
                    m_current = new CodeDomAssistantConfig();
                }

                return m_current;
            }
            set
            {
                m_current = value;
            }
        }
    }
}
